package demoMod.anm2editor.ui;

import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.Input;
import com.badlogic.gdx.graphics.Color;
import com.badlogic.gdx.graphics.g2d.BitmapFont;
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
import demoMod.anm2editor.fonts.FontKeys;
import demoMod.anm2editor.localization.LocalizedStrings;
import demoMod.anm2editor.model.*;
import demoMod.gdxform.abstracts.Container;
import demoMod.gdxform.core.FormManager;
import demoMod.gdxform.helpers.FontHelper;
import demoMod.gdxform.interfaces.Element;
import demoMod.gdxform.interfaces.MouseEventSubscriber;
import demoMod.gdxform.ui.*;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class AnimationItem implements Element, MouseEventSubscriber {
    private Container<? extends Element> parent;
    private String id = "";
    private final Animation animation;
    private final GLabel animationName;

    public AnimationItem(float width, float height, Animation animation, BitmapFont animationNameFont) {
        this.animation = animation;
        this.animationName = new GLabel(0, animationNameFont.getLineHeight() / 2.0F, width, height, animationNameFont);
        this.animationName.setColor(Color.WHITE.cpy());
        this.animationName.setText(animation.getName());
    }

    public Animation getAnimation() {
        return animation;
    }

    @Override
    public String getId() {
        return id;
    }

    @Override
    public void setId(String id) {
        this.id = id;
    }

    @Override
    public void update() {

    }

    @Override
    public void render(SpriteBatch sb) {
        sb.setColor(Color.WHITE.cpy());
        this.animationName.setX(getX(true) + 5.0F);
        this.animationName.setY(getY(true) + this.animationName.getFont().getLineHeight() / 2.0F);
        this.animationName.render(sb);
    }

    @Override
    public Container<? extends Element> getParent() {
        return this.parent;
    }

    @Override
    public void setParent(Container<? extends Element> parent) {
        this.parent = parent;
    }

    @Override
    public float getX(boolean isAbsolute) {
        return getParent() != null ? getParent().getX(isAbsolute) : 0;
    }

    @Override
    public float getY(boolean isAbsolute) {
        return getParent() != null ? getParent().getY(isAbsolute) : 0;
    }

    @Override
    public void setX(float x) {

    }

    @Override
    public void setY(float y) {

    }

    @Override
    public float getWidth() {
        return getParent() != null ? getParent().getWidth() : Gdx.graphics.getWidth();
    }

    @Override
    public float getHeight() {
        return getParent() != null ? getParent().getHeight() : Gdx.graphics.getHeight();
    }

    @Override
    public void setWidth(float width) {

    }

    @Override
    public void setHeight(float height) {

    }

    @Override
    public Color getBackground() {
        return null;
    }

    @Override
    public void setBackground(Color background) {

    }

    @Override
    public boolean isResizable() {
        return false;
    }

    @Override
    public void setResizable(boolean resizable) {

    }

    @Override
    public boolean enabled() {
        return false;
    }

    @Override
    public void setEnabled(boolean enabled) {

    }

    @Override
    public boolean visible() {
        return false;
    }

    @Override
    public void setVisible(boolean visible) {

    }

    @Override
    public void dispose() {
        this.animationName.dispose();
    }

    @Override
    public boolean clickDown(int screenX, int screenY, int button) {
        if (screenX > getX(true) && screenX < getX(true) + getWidth() && Gdx.graphics.getHeight() - screenY > getY(true)
                && Gdx.graphics.getHeight() - screenY < getY(true) + getHeight()) {
            List<String> strings = LocalizedStrings.getStrings("AnimationItem");
            if (getParent() != null && getParent().getParent() instanceof AnimationList && !((GList.ListCellRenderer<AnimationItem>) getParent()).isSelected()) {
                Animation prevAnimation = Project.currentProject.getCurrentAnimation();
                Project.currentProject.setCurrentAnimation(animation);
                ((Timeline) FormManager.getInstance().getContainerById(Timeline.ID)).clearTrack();
                ((TrackPane) FormManager.getInstance().getContainerById(TrackPane.ID)).clearTrack();
                for (Track track : Project.currentProject.getTracks()) {
                    ((Timeline) FormManager.getInstance().getContainerById(Timeline.ID)).addTrack(animation.getName(), track);
                    ((TrackPane) FormManager.getInstance().getContainerById(TrackPane.ID)).addTrack(track);
                }
                StatusBar statusBar = (StatusBar) FormManager.getInstance().getContainerById(StatusBar.ID);
                GTextField animationLength = (GTextField) statusBar.getElementById("animationLength");
                animationLength.setText(Integer.toString(animation.getAnimationLength()));
                Operation operation = new Operation() {
                    @Override
                    public void undo() {
                        Project.currentProject.setCurrentAnimation(prevAnimation);
                        ((Timeline) FormManager.getInstance().getContainerById(Timeline.ID)).clearTrack();
                        ((TrackPane) FormManager.getInstance().getContainerById(TrackPane.ID)).clearTrack();
                        for (Track track : Project.currentProject.getTracks()) {
                            ((Timeline) FormManager.getInstance().getContainerById(Timeline.ID)).addTrack(prevAnimation.getName(), track);
                            ((TrackPane) FormManager.getInstance().getContainerById(TrackPane.ID)).addTrack(track);
                        }
                        StatusBar statusBar = (StatusBar) FormManager.getInstance().getContainerById(StatusBar.ID);
                        GTextField animationLength = (GTextField) statusBar.getElementById("animationLength");
                        animationLength.setText(Integer.toString(prevAnimation.getAnimationLength()));
                    }

                    @Override
                    public void redo() {
                        Project.currentProject.setCurrentAnimation(animation);
                        ((Timeline) FormManager.getInstance().getContainerById(Timeline.ID)).clearTrack();
                        ((TrackPane) FormManager.getInstance().getContainerById(TrackPane.ID)).clearTrack();
                        for (Track track : Project.currentProject.getTracks()) {
                            ((Timeline) FormManager.getInstance().getContainerById(Timeline.ID)).addTrack(animation.getName(), track);
                            ((TrackPane) FormManager.getInstance().getContainerById(TrackPane.ID)).addTrack(track);
                        }
                        StatusBar statusBar = (StatusBar) FormManager.getInstance().getContainerById(StatusBar.ID);
                        GTextField animationLength = (GTextField) statusBar.getElementById("animationLength");
                        animationLength.setText(Integer.toString(animation.getAnimationLength()));
                    }
                };
                operation.setName(strings.get(14));
                ((HistoryPanel) FormManager.getInstance().getContainerById(HistoryPanel.ID)).addOperation(operation);
            } else if (getParent() != null && getParent().getParent() instanceof AnimationList && button == Input.Buttons.RIGHT) {
                int index = ((AnimationList)getParent().getParent()).indexOf(this);
                GMenuList menuList = new GMenuList();
                menuList.setWidth(150.0F);
                menuList.setX(screenX - menuList.getWidth());
                menuList.setY(Gdx.graphics.getHeight() - screenY);
                GMenuItem newAnimation = new GMenuItem(menuList.getWidth(), menuList.getMenuItemHeight(), strings.get(0) + "...", FontHelper.getFont(FontKeys.SIM_HEI_14)) {
                    @Override
                    public void onClick() {
                        TextInputWindow textInputWindow = new TextInputWindow(strings.get(1), "", FontHelper.getFont(FontKeys.SIM_HEI_14));
                        textInputWindow.setConfirmCallback(name -> {
                            List<GCheckBox> options = new ArrayList<>();
                            GCheckBox loop = new GCheckBox(0, 0, 16, 16, FontHelper.getFont(FontKeys.SIM_HEI_14));
                            loop.setText(strings.get(2));
                            GCheckBox defaultAnimation = new GCheckBox(0, 0, 16, 16, FontHelper.getFont(FontKeys.SIM_HEI_14));
                            defaultAnimation.setText(strings.get(3));
                            options.add(loop);
                            options.add(defaultAnimation);
                            CheckBoxWindow checkBoxWindow = new CheckBoxWindow(strings.get(4), options, FontHelper.getFont(FontKeys.SIM_HEI_14));
                            checkBoxWindow.setConfirmCallback(checkBoxList -> {
                                Animation animation = new Animation();
                                animation.setName(name);
                                if (checkBoxList.get(1).getState() == 1) {
                                    for (Animation animation1 : Project.currentProject.getAnimations()) {
                                        animation1.setDefaultAnimation(false);
                                    }
                                    animation.setDefaultAnimation(true);
                                }
                                animation.setLoop(checkBoxList.get(0).getState() == 1);
                                Project.currentProject.getAnimations().add(animation);
                                AnimationPane animationPane = (AnimationPane) FormManager.getInstance().getContainerById(AnimationPane.ID);
                                AnimationItem itemToAdd = new AnimationItem(animationPane.getWidth(), animationPane.getAnimationList().getCellHeight(), animation, FontHelper.getFont(FontKeys.SIM_HEI_16));
                                itemToAdd.setId(animation.getName());
                                animationPane.getAnimationList().addItem(index, itemToAdd);
                                if (animation.isDefaultAnimation()) {
                                    animationPane.getAnimationList().setSelected(index, true);
                                }
                                List<TrackContent> trackContents = new ArrayList<>();
                                for (Track track : Project.currentProject.getTracks()) {
                                    TrackContent content = new TrackContent().setKeyFrames(new ArrayList<>());
                                    track.addContent(animation.getName(), content);
                                    trackContents.add(content);
                                }
                                ((AnimationPane) FormManager.getInstance().getContainerById(AnimationPane.ID)).selectAnimation(index, false);
                                Project.currentProject.setCurrentAnimation(animation);
                                ((Timeline) FormManager.getInstance().getContainerById(Timeline.ID)).clearTrack();
                                ((TrackPane) FormManager.getInstance().getContainerById(TrackPane.ID)).clearTrack();
                                for (Track track : Project.currentProject.getTracks()) {
                                    ((Timeline) FormManager.getInstance().getContainerById(Timeline.ID)).addTrack(animation.getName(), track);
                                    ((TrackPane) FormManager.getInstance().getContainerById(TrackPane.ID)).addTrack(track);
                                }
                                ((AnimationPane) FormManager.getInstance().getContainerById(AnimationPane.ID)).selectAnimation(index + 1, true);
                                GScrollPane scrollPane = ((AnimationPane) FormManager.getInstance().getContainerById(AnimationPane.ID)).getScrollPane();
                                if (Project.currentProject.getAnimations().size() * ((Timeline) FormManager.getInstance().getContainerById(Timeline.ID)).getTrackHeight() > scrollPane.getPlainHeight()) {
                                    scrollPane.setPlainHeight(scrollPane.getPlainHeight() + 3 * ((Timeline) FormManager.getInstance().getContainerById(Timeline.ID)).getTrackHeight());
                                }
                                for (Event event : Project.currentProject.getEvents()) {
                                    event.getUsages().put(animation.getName(), new ArrayList<>());
                                }
                                Operation operation = new Operation() {
                                    @Override
                                    public void undo() {
                                        Project.currentProject.getAnimations().remove(animation);
                                        ((AnimationPane)FormManager.getInstance().getContainerById(AnimationPane.ID)).removeAnimation(animation);
                                        for (Track track : Project.currentProject.getTracks()) {
                                            track.removeContent(animation.getName());
                                        }
                                        if (index > 0) {
                                            ((AnimationPane) FormManager.getInstance().getContainerById(AnimationPane.ID)).selectAnimation(index - 1, true);
                                            Project.currentProject.setCurrentAnimation(Project.currentProject.getAnimations().get(index - 1));
                                        }
                                        Animation currentAnimation = Project.currentProject.getCurrentAnimation();
                                        ((Timeline) FormManager.getInstance().getContainerById(Timeline.ID)).clearTrack();
                                        ((TrackPane) FormManager.getInstance().getContainerById(TrackPane.ID)).clearTrack();
                                        if (currentAnimation != null) {
                                            for (Track track : Project.currentProject.getTracks()) {
                                                ((Timeline) FormManager.getInstance().getContainerById(Timeline.ID)).addTrack(currentAnimation.getName(), track);
                                                ((TrackPane) FormManager.getInstance().getContainerById(TrackPane.ID)).addTrack(track);
                                            }
                                        }
                                        for (Event event : Project.currentProject.getEvents()) {
                                            event.getUsages().remove(animation.getName());
                                        }
                                        GScrollPane scrollPane = ((AnimationPane) FormManager.getInstance().getContainerById(AnimationPane.ID)).getScrollPane();
                                        if (scrollPane.getPlainHeight() - Project.currentProject.getAnimations().size() > 3 * ((Timeline) FormManager.getInstance().getContainerById(Timeline.ID)).getTrackHeight()) {
                                            float plainHeight = scrollPane.getPlainHeight() - 3 * ((Timeline) FormManager.getInstance().getContainerById(Timeline.ID)).getTrackHeight();
                                            if (FormManager.getInstance().getContainerById(AnimationPane.ID).getHeight() * 2 > plainHeight) {
                                                plainHeight = FormManager.getInstance().getContainerById(AnimationPane.ID).getHeight() * 2;
                                            }
                                            scrollPane.setPlainHeight(plainHeight);
                                        }
                                    }

                                    @Override
                                    public void redo() {
                                        Project.currentProject.getAnimations().add(animation);
                                        animationPane.getAnimationList().addItem(index, itemToAdd);
                                        if (animation.isDefaultAnimation()) {
                                            animationPane.getAnimationList().setSelected(index, true);
                                        }
                                        int i = 0;
                                        for (Track track : Project.currentProject.getTracks()) {
                                            track.addContent(animation.getName(), trackContents.get(i));
                                            i++;
                                        }
                                        Project.currentProject.setCurrentAnimation(animation);
                                        ((Timeline) FormManager.getInstance().getContainerById(Timeline.ID)).clearTrack();
                                        ((TrackPane) FormManager.getInstance().getContainerById(TrackPane.ID)).clearTrack();
                                        for (Track track : Project.currentProject.getTracks()) {
                                            ((Timeline) FormManager.getInstance().getContainerById(Timeline.ID)).addTrack(animation.getName(), track);
                                            ((TrackPane) FormManager.getInstance().getContainerById(TrackPane.ID)).addTrack(track);
                                        }
                                        GScrollPane scrollPane = ((AnimationPane) FormManager.getInstance().getContainerById(AnimationPane.ID)).getScrollPane();
                                        if (Project.currentProject.getAnimations().size() * ((Timeline) FormManager.getInstance().getContainerById(Timeline.ID)).getTrackHeight() > scrollPane.getPlainHeight()) {
                                            scrollPane.setPlainHeight(scrollPane.getPlainHeight() + 3 * ((Timeline) FormManager.getInstance().getContainerById(Timeline.ID)).getTrackHeight());
                                        }
                                        for (Event event : Project.currentProject.getEvents()) {
                                            event.getUsages().put(animation.getName(), new ArrayList<>());
                                        }
                                    }
                                };
                                operation.setName(strings.get(5));
                                ((HistoryPanel) FormManager.getInstance().getContainerById(HistoryPanel.ID)).addOperation(operation);
                            });
                        });
                    }
                };
                GMenuItem rename = new GMenuItem(menuList.getWidth(), menuList.getMenuItemHeight(), strings.get(6) + "...", FontHelper.getFont(FontKeys.SIM_HEI_14)) {
                    @Override
                    public void onClick() {
                        TextInputWindow textInputWindow = new TextInputWindow(strings.get(7), animation.getName(), FontHelper.getFont(FontKeys.SIM_HEI_14));
                        textInputWindow.setConfirmCallback(name -> {
                            if (name.length() > 0) {
                                String nameBefore = animation.getName();
                                for (Track track : Project.currentProject.getTracks()) {
                                    TrackContent content = track.getContent(nameBefore);
                                    track.removeContent(nameBefore);
                                    track.addContent(name, content);
                                }
                                for (Event event : Project.currentProject.getEvents()) {
                                    event.getUsages().put(name, event.getUsages().remove(nameBefore));
                                }
                                animation.setName(name);
                                animationName.setText(name);
                                Operation operation = new Operation() {
                                    @Override
                                    public void undo() {
                                        for (Track track : Project.currentProject.getTracks()) {
                                            TrackContent content = track.getContent(name);
                                            track.removeContent(name);
                                            track.addContent(nameBefore, content);
                                        }
                                        for (Event event : Project.currentProject.getEvents()) {
                                            event.getUsages().put(nameBefore, event.getUsages().remove(name));
                                        }
                                        animation.setName(nameBefore);
                                        animationName.setText(nameBefore);
                                    }

                                    @Override
                                    public void redo() {
                                        for (Track track : Project.currentProject.getTracks()) {
                                            TrackContent content = track.getContent(nameBefore);
                                            track.removeContent(nameBefore);
                                            track.addContent(name, content);
                                        }
                                        for (Event event : Project.currentProject.getEvents()) {
                                            event.getUsages().put(name, event.getUsages().remove(nameBefore));
                                        }
                                        animation.setName(name);
                                        animationName.setText(name);
                                    }
                                };
                                operation.setName(strings.get(8));
                                ((HistoryPanel) FormManager.getInstance().getContainerById(HistoryPanel.ID)).addOperation(operation);
                            }
                        });
                    }
                };
                GMenuItem delete = new GMenuItem(menuList.getWidth(), menuList.getMenuItemHeight(), strings.get(9), FontHelper.getFont(FontKeys.SIM_HEI_14)) {
                    @Override
                    public void onClick() {
                        ((AnimationPane)FormManager.getInstance().getContainerById(AnimationPane.ID)).removeAnimation(animation);
                        Project.currentProject.getAnimations().remove(animation);
                        ((Timeline) FormManager.getInstance().getContainerById(Timeline.ID)).clearTrack();
                        ((TrackPane) FormManager.getInstance().getContainerById(TrackPane.ID)).clearTrack();
                        List<TrackContent> trackContents = new ArrayList<>();
                        for (Track track : Project.currentProject.getTracks()) {
                            trackContents.add(track.getContent(animation.getName()));
                            track.removeContent(animation.getName());
                        }
                        Map<Integer, List<Integer>> usages = new HashMap<>();
                        for (Event event : Project.currentProject.getEvents()) {
                            usages.put(event.getId(), event.getUsages().remove(animation.getName()));
                        }
                        if (!Project.currentProject.getAnimations().isEmpty()) {
                            int t = index - 1;
                            if (t < 0) t = 0;
                            Project.currentProject.setCurrentAnimation(Project.currentProject.getAnimations().get(t));
                            for (Track track : Project.currentProject.getTracks()) {
                                ((Timeline) FormManager.getInstance().getContainerById(Timeline.ID)).addTrack(Project.currentProject.getCurrentAnimation().getName(), track);
                                ((TrackPane) FormManager.getInstance().getContainerById(TrackPane.ID)).addTrack(track);
                            }
                            ((AnimationPane)FormManager.getInstance().getContainerById(AnimationPane.ID)).selectAnimation(t, true);
                            GScrollPane scrollPane = ((AnimationPane) FormManager.getInstance().getContainerById(AnimationPane.ID)).getScrollPane();
                            if (scrollPane.getPlainHeight() - Project.currentProject.getAnimations().size() > 3 * ((Timeline) FormManager.getInstance().getContainerById(Timeline.ID)).getTrackHeight()) {
                                float plainHeight = scrollPane.getPlainHeight() - 3 * ((Timeline) FormManager.getInstance().getContainerById(Timeline.ID)).getTrackHeight();
                                if (FormManager.getInstance().getContainerById(AnimationPane.ID).getHeight() * 2 > plainHeight) {
                                    plainHeight = FormManager.getInstance().getContainerById(AnimationPane.ID).getHeight() * 2;
                                }
                                scrollPane.setPlainHeight(plainHeight);
                            }
                        }
                        Operation operation = new Operation() {
                            @Override
                            public void undo() {
                                AnimationPane animationPane = (AnimationPane) FormManager.getInstance().getContainerById(AnimationPane.ID);
                                AnimationItem itemToAdd = new AnimationItem(animationPane.getWidth(), animationPane.getAnimationList().getCellHeight(), animation, FontHelper.getFont(FontKeys.SIM_HEI_16));
                                itemToAdd.setId(animation.getName());
                                Project.currentProject.getAnimations().add(animation);
                                animationPane.getAnimationList().addItem(index - 1, itemToAdd);
                                if (animation.isDefaultAnimation()) {
                                    animationPane.getAnimationList().setSelected(index - 1, true);
                                }
                                int i = 0;
                                for (Track track : Project.currentProject.getTracks()) {
                                    track.addContent(animation.getName(), trackContents.get(i));
                                    i++;
                                }
                                Project.currentProject.setCurrentAnimation(animation);
                                ((Timeline) FormManager.getInstance().getContainerById(Timeline.ID)).clearTrack();
                                ((TrackPane) FormManager.getInstance().getContainerById(TrackPane.ID)).clearTrack();
                                for (Track track : Project.currentProject.getTracks()) {
                                    ((Timeline) FormManager.getInstance().getContainerById(Timeline.ID)).addTrack(animation.getName(), track);
                                    ((TrackPane) FormManager.getInstance().getContainerById(TrackPane.ID)).addTrack(track);
                                }
                                GScrollPane scrollPane = ((AnimationPane) FormManager.getInstance().getContainerById(AnimationPane.ID)).getScrollPane();
                                if (Project.currentProject.getAnimations().size() * ((Timeline) FormManager.getInstance().getContainerById(Timeline.ID)).getTrackHeight() > scrollPane.getPlainHeight()) {
                                    scrollPane.setPlainHeight(scrollPane.getPlainHeight() + 3 * ((Timeline) FormManager.getInstance().getContainerById(Timeline.ID)).getTrackHeight());
                                }
                                for (Event event : Project.currentProject.getEvents()) {
                                    if (usages.get(event.getId()) != null) event.getUsages().put(animation.getName(), usages.get(event.getId()));
                                }
                            }

                            @Override
                            public void redo() {
                                ((AnimationPane)FormManager.getInstance().getContainerById(AnimationPane.ID)).removeAnimation(animation);
                                Project.currentProject.getAnimations().remove(animation);
                                ((Timeline) FormManager.getInstance().getContainerById(Timeline.ID)).clearTrack();
                                ((TrackPane) FormManager.getInstance().getContainerById(TrackPane.ID)).clearTrack();
                                for (Track track : Project.currentProject.getTracks()) {
                                    track.removeContent(animation.getName());
                                }
                                for (Event event : Project.currentProject.getEvents()) {
                                    event.getUsages().remove(animation.getName());
                                }
                                if (!Project.currentProject.getAnimations().isEmpty()) {
                                    int t = index - 1;
                                    if (t < 0) t = 0;
                                    Project.currentProject.setCurrentAnimation(Project.currentProject.getAnimations().get(t));
                                    for (Track track : Project.currentProject.getTracks()) {
                                        ((Timeline) FormManager.getInstance().getContainerById(Timeline.ID)).addTrack(Project.currentProject.getCurrentAnimation().getName(), track);
                                        ((TrackPane) FormManager.getInstance().getContainerById(TrackPane.ID)).addTrack(track);
                                    }
                                    ((AnimationPane)FormManager.getInstance().getContainerById(AnimationPane.ID)).selectAnimation(t, true);
                                    GScrollPane scrollPane = ((AnimationPane) FormManager.getInstance().getContainerById(AnimationPane.ID)).getScrollPane();
                                    if (scrollPane.getPlainHeight() - Project.currentProject.getAnimations().size() > 3 * ((Timeline) FormManager.getInstance().getContainerById(Timeline.ID)).getTrackHeight()) {
                                        float plainHeight = scrollPane.getPlainHeight() - 3 * ((Timeline) FormManager.getInstance().getContainerById(Timeline.ID)).getTrackHeight();
                                        if (FormManager.getInstance().getContainerById(AnimationPane.ID).getHeight() * 2 > plainHeight) {
                                            plainHeight = FormManager.getInstance().getContainerById(AnimationPane.ID).getHeight() * 2;
                                        }
                                        scrollPane.setPlainHeight(plainHeight);
                                    }
                                }
                            }
                        };
                        operation.setName(strings.get(10));
                        ((HistoryPanel) FormManager.getInstance().getContainerById(HistoryPanel.ID)).addOperation(operation);
                    }
                };
                GMenuItem duplicate = new GMenuItem(menuList.getWidth(), menuList.getMenuItemHeight(), strings.get(11), FontHelper.getFont(FontKeys.SIM_HEI_14)) {
                    @Override
                    public void onClick() {
                        Animation animation = new Animation();
                        animation.setName(AnimationItem.this.animation.getName() + " " + strings.get(12));
                        animation.setLoop(AnimationItem.this.animation.isLoop());
                        animation.setDefaultAnimation(false);
                        animation.setAnimationLength(AnimationItem.this.animation.getAnimationLength());
                        Project.currentProject.getAnimations().add(index + 1, animation);
                        ((AnimationPane)FormManager.getInstance().getContainerById(AnimationPane.ID)).addAnimation(index, animation);
                        Map<Integer, TrackContent> copiedTrackContent = new HashMap<>();
                        for (Track track : Project.currentProject.getTracks()) {
                            TrackContent content = track.getContent(AnimationItem.this.animation.getName());
                            List<KeyFrame> keyFrames = new ArrayList<>();
                            for (KeyFrame keyFrame : content.getKeyFrames()) {
                                keyFrames.add(keyFrame.makeCopy());
                            }
                            track.addContent(animation.getName(), new TrackContent().setKeyFrames(keyFrames));
                            copiedTrackContent.put(track.getId(),track.getContent(animation.getName()));
                        }
                        GScrollPane scrollPane = ((AnimationPane) FormManager.getInstance().getContainerById(AnimationPane.ID)).getScrollPane();
                        if (Project.currentProject.getAnimations().size() * ((Timeline) FormManager.getInstance().getContainerById(Timeline.ID)).getTrackHeight() > scrollPane.getPlainHeight()) {
                            scrollPane.setPlainHeight(scrollPane.getPlainHeight() + 3 * ((Timeline) FormManager.getInstance().getContainerById(Timeline.ID)).getTrackHeight());
                        }
                        Map<Integer, List<Integer>> cpyUsages = new HashMap<>();
                        for (Event event : Project.currentProject.getEvents()) {
                            List<Integer> usages = event.getUsages().computeIfAbsent(AnimationItem.this.animation.getName(), k -> new ArrayList<>());
                            List<Integer> cpy = new ArrayList<>(usages);
                            event.getUsages().put(animation.getName(), cpy);
                            cpyUsages.put(event.getId(), cpy);
                        }
                        Operation operation = new Operation() {
                            @Override
                            public void undo() {
                                Project.currentProject.getAnimations().remove(animation);
                                ((AnimationPane)FormManager.getInstance().getContainerById(AnimationPane.ID)).removeAnimation(animation);
                                for (Track track : Project.currentProject.getTracks()) {
                                    track.removeContent(animation.getName());
                                }
                                Animation currentAnimation = Project.currentProject.getCurrentAnimation();
                                ((Timeline) FormManager.getInstance().getContainerById(Timeline.ID)).clearTrack();
                                ((TrackPane) FormManager.getInstance().getContainerById(TrackPane.ID)).clearTrack();
                                if (currentAnimation != null) {
                                    for (Track track : Project.currentProject.getTracks()) {
                                        ((Timeline) FormManager.getInstance().getContainerById(Timeline.ID)).addTrack(currentAnimation.getName(), track);
                                        ((TrackPane) FormManager.getInstance().getContainerById(TrackPane.ID)).addTrack(track);
                                    }
                                }
                                for (Event event : Project.currentProject.getEvents()) {
                                    event.getUsages().remove(animation.getName());
                                }
                                GScrollPane scrollPane = ((AnimationPane) FormManager.getInstance().getContainerById(AnimationPane.ID)).getScrollPane();
                                if (scrollPane.getPlainHeight() - Project.currentProject.getAnimations().size() > 3 * ((Timeline) FormManager.getInstance().getContainerById(Timeline.ID)).getTrackHeight()) {
                                    float plainHeight = scrollPane.getPlainHeight() - 3 * ((Timeline) FormManager.getInstance().getContainerById(Timeline.ID)).getTrackHeight();
                                    if (FormManager.getInstance().getContainerById(AnimationPane.ID).getHeight() * 2 > plainHeight) {
                                        plainHeight = FormManager.getInstance().getContainerById(AnimationPane.ID).getHeight() * 2;
                                    }
                                    scrollPane.setPlainHeight(plainHeight);
                                }
                            }

                            @Override
                            public void redo() {
                                Project.currentProject.getAnimations().add(index + 1, animation);
                                ((AnimationPane)FormManager.getInstance().getContainerById(AnimationPane.ID)).addAnimation(index, animation);
                                for (Track track : Project.currentProject.getTracks()) {
                                    track.addContent(animation.getName(), copiedTrackContent.get(track.getId()));
                                }
                                GScrollPane scrollPane = ((AnimationPane) FormManager.getInstance().getContainerById(AnimationPane.ID)).getScrollPane();
                                if (Project.currentProject.getAnimations().size() * ((Timeline) FormManager.getInstance().getContainerById(Timeline.ID)).getTrackHeight() > scrollPane.getPlainHeight()) {
                                    scrollPane.setPlainHeight(scrollPane.getPlainHeight() + 3 * ((Timeline) FormManager.getInstance().getContainerById(Timeline.ID)).getTrackHeight());
                                }
                                for (Event event : Project.currentProject.getEvents()) {
                                    event.getUsages().put(animation.getName(), cpyUsages.get(event.getId()));
                                }
                            }
                        };
                        operation.setName(strings.get(13));
                        ((HistoryPanel) FormManager.getInstance().getContainerById(HistoryPanel.ID)).addOperation(operation);
                    }
                };
                duplicate.setSplitLine(false);
                menuList.addElement(newAnimation);
                menuList.addElement(rename);
                menuList.addElement(delete);
                menuList.addElement(duplicate);
                FormManager.getInstance().addContainer(menuList);
                FormManager.getInstance().moveToTop(menuList);
            }
            return true;
        }
        return false;
    }

    @Override
    public boolean clickUp(int screenX, int screenY, int button) {
        return false;
    }

    @Override
    public boolean mouseDragged(int screenX, int screenY) {
        return false;
    }

    @Override
    public boolean mouseMoved(int screenX, int screenY) {
        return false;
    }

    @Override
    public boolean scrolled(int amount) {
        return false;
    }

    @Override
    public boolean moveToElementBorder(Element element) {
        return false;
    }
}
